
#ifndef __AHB_DMA020_H
#define __AHB_DMA020_H

#include "unione_lite.h"

#define DMA_INT_POLLING
//extern volatile UINT32	bWaitIntCB[8];

//#define TEST_MEMORY_BASE			0x42000000
//#define QC_MODE                                 0x80

//#define DMA020_BASE					CPE_DMA_BASE
#define IRQ_DMA020					11
#define IRQ_DMA020_TC				10

/* registers */
#define DMA_INT						0x0
#define DMA_INT_TC					0x4
#define DMA_INT_TC_CLR				0x8
#define DMA_INT_ERRABT				0xC
#define DMA_INT_ERRABT_CLR			0x10
#define DMA_TC						0x14
#define DMA_ERRABT					0x18
#define DMA_CH_EN					0x1C
#define DMA_CH_BUSY					0x20
#define DMA_CSR						0x24
#define DMA_SYNC					0x28

#define DMA_FEATURE					0x34  // new
#define DMA_C0_DevDtBase			0x40  // new
#define DMA_C0_DevRegBase			0x80  // new


#define DMA_CHANNEL_OFFSET			0x20
#define DMA_CHANNEL0_BASE			0x100
#define DMA_CHANNEL1_BASE			0x120
#define DMA_CHANNEL2_BASE			0x140
#define DMA_CHANNEL3_BASE			0x160
#define DMA_CHANNEL4_BASE			0x180
#define DMA_CHANNEL5_BASE			0x1a0
#define DMA_CHANNEL6_BASE			0x1c0
#define DMA_CHANNEL7_BASE			0x1e0

#define DMA_CHANNEL_CSR_OFFSET		0x0
#define DMA_CHANNEL_CFG_OFFSET		0x4
#define DMA_CHANNEL_SRCADDR_OFFSET	0x8
#define DMA_CHANNEL_DSTADDR_OFFSET	0xc
#define DMA_CHANNEL_LLP_OFFSET		0x10
#define DMA_CHANNEL_SIZE_OFFSET		0x14


/* bit mapping of main configuration status register(CSR 0x24) */
#define DMA_CSR_M1ENDIAN			0x00000004
#define DMA_CSR_M0ENDIAN			0x00000002
#define DMA_CSR_DMACEN				0x00000001

/* bit mapping of channel control register 0x100 */
#define DMA_CSR_TC_MSK				0x80000000
#define DMA_CSR_CHPRJ_HIGHEST		0x00C00000
#define DMA_CSR_CHPRJ_2ND			0x00800000
#define DMA_CSR_CHPRJ_3RD			0x00400000
#define DMA_CSR_PRTO3				0x00200000
#define DMA_CSR_PRTO2				0x00100000
#define DMA_CSR_PRTO1				0x00080000
#define DMA_CSR_SRC_BURST_SIZE_1	0x00000000
#define DMA_CSR_SRC_BURST_SIZE_4	0x00010000
#define DMA_CSR_SRC_BURST_SIZE_8	0x00020000
#define DMA_CSR_SRC_BURST_SIZE_16	0x00030000
#define DMA_CSR_SRC_BURST_SIZE_32	0x00040000
#define DMA_CSR_SRC_BURST_SIZE_64	0x00050000
#define DMA_CSR_SRC_BURST_SIZE_128	0x00060000
#define DMA_CSR_SRC_BURST_SIZE_256	0x00070000

#define DMA_CSR_ABT					0x00008000

#define DMA_CSR_SRC_WIDTH_8			0x00000000
#define DMA_CSR_SRC_WIDTH_16		0x00000800
#define DMA_CSR_SRC_WIDTH_32		0x00001000
#define DMA_CSR_SRC_WIDTH_64		0x00001800   //new

#define DMA_CSR_DST_WIDTH_8			0x00000000
#define DMA_CSR_DST_WIDTH_16		0x00000100
#define DMA_CSR_DST_WIDTH_32		0x00000200   
#define DMA_CSR_DST_WIDTH_64		0x00000300   //new

#define DMA_CSR_MODE_NORMAL			0x00000000
#define DMA_CSR_MODE_HANDSHAKE		0x00000080

#define DMA_CSR_SRC_INCREMENT		0x00000000
#define DMA_CSR_SRC_DECREMENT		0x00000020
#define DMA_CSR_SRC_FIX				0x00000040

#define DMA_CSR_DST_INCREMENT		0x00000000
#define DMA_CSR_DST_DECREMENT		0x00000008
#define DMA_CSR_DST_FIX				0x00000010

#define DMA_CSR_SRC_SEL				0x00000004
#define DMA_CSR_DST_SEL				0x00000002
#define DMA_CSR_CH_ENABLE			0x00000001

#define DMA_CSR_DMA_FF_TH			0x07000000   //new
#define DMA_CSR_CHPR1				0x00C00000
#define DMA_CSR_SRC_SIZE			0x00070000
#define DMA_CSR_SRC_WIDTH			0x00003800
#define DMA_CSR_DST_WIDTH			0x00000700
#define DMA_CSR_SRCAD_CTL			0x00000060
#define DMA_CSR_DSTAD_CTL			0x00000018

/* bit mapping of channel configuration register 0x104 */
#define DMA_CFG_INT_ABT_MSK	        0x00000004   // new
#define DMA_CFG_INT_ERR_MSK	        0x00000002   // new
#define DMA_CFG_INT_TC_MSK	        0x00000001   // new

///////////////////////////////////////////////////
/* bit mapping of Linked List Control Descriptor */

#define DMA_LLP_DMA_FF_TH			0xE0000000   // new

#define DMA_LLP_TC_MSK				0x10000000

#define DMA_LLP_SRC_WIDTH_8			0x00000000
#define DMA_LLP_SRC_WIDTH_16		0x02000000
#define DMA_LLP_SRC_WIDTH_32		0x04000000
#define DMA_LLP_SRC_WIDTH_64		0x06000000   // new

#define DMA_LLP_DST_WIDTH_8			0x00000000
#define DMA_LLP_DST_WIDTH_16		0x00400000
#define DMA_LLP_DST_WIDTH_32		0x00800000
#define DMA_LLP_DST_WIDTH_64		0x00C00000   // new

#define DMA_LLP_SRC_INCREMENT		0x00000000
#define DMA_LLP_SRC_DECREMENT		0x00100000
#define DMA_LLP_SRC_FIX				0x00200000

#define DMA_LLP_DST_INCREMENT		0x00000000
#define DMA_LLP_DST_DECREMENT		0x00040000
#define DMA_LLP_DST_FIX				0x00080000

#define DMA_LLP_SRC_SEL				0x00020000
#define DMA_LLP_DST_SEL				0x00010000

///////////////////////////////////////#define DMA_MAX_SIZE				0x10000
///////////////////////////////////////#define DMA_CHANNEL_NUMBER			8

/////////////////////////// AHB DMA Define //////////////////////////////////
#define AHBDMA_Channel0					0
#define AHBDMA_Channel1					1
#define AHBDMA_Channel2					2
#define AHBDMA_Channel3					3
#define AHBDMA_Channel4					4
#define AHBDMA_Channel5					5
#define AHBDMA_Channel6					6
#define AHBDMA_Channel7					7
#define AHBDMA_Channel_MAX				8

#define AHBDMA_SrcWidth_Byte			0
#define AHBDMA_SrcWidth_Word			1
#define AHBDMA_SrcWidth_DWord			2

#define AHBDMA_DstWidth_Byte			0
#define AHBDMA_DstWidth_Word			1
#define AHBDMA_DstWidth_DWord			2

#define AHBDMA_Burst1					0
#define AHBDMA_Burst4					1
#define AHBDMA_Burst8					2
#define AHBDMA_Burst16					3
#define AHBDMA_Burst32					4
#define AHBDMA_Burst64					5
#define AHBDMA_Burst128					6
#define AHBDMA_Burst256					7
#define AHBDMA_SrcSize_MAX				8

#define AHBDMA_NormalMode				0
#define AHBDMA_HwHandShakeMode			1

#define AHBDMA_SrcInc					0
#define AHBDMA_SrcDec					1
#define AHBDMA_SrcFix					2

#define AHBDMA_DstInc					0
#define AHBDMA_DstDec					1
#define AHBDMA_DstFix					2

#define AHBDMA_PriorityLow				0
#define AHBDMA_Priority3rd				1
#define AHBDMA_Priority2nd				2
#define AHBDMA_PriorityHigh				3

#define AHBDMA_PROT1					0x1
#define AHBDMA_PROT2					0x2
#define AHBDMA_PROT3					0x4

#define AHBDMA_MAX_LLDSIZE				0x3FFFFC	//4M-4, new

// feature register, new
#ifndef __BIG_ENDIAN //for little endian
typedef struct
{
	UINT32 FF_ADDR_WIDTH:4;
	UINT32 Reserved1:4;
	UINT32 SupportLL:1;
	UINT32 HaveAHB1:1;
	UINT32 Reserved2:1;
	UINT32 Reserved3:1;
	UINT32 MaxChNo:4;
	UINT32 Reserved4:16;
} fLib_DMA_FEATURE_t;	
#else //for big endian
typedef struct
{
	UINT32 Reserved4:16;
	UINT32 MaxChNo:4;
	UINT32 Reserved3:1;
	UINT32 Reserved2:1;
	UINT32 HaveAHB1:1;
	UINT32 SupportLL:1;
	UINT32 Reserved1:4;
	UINT32 FF_ADDR_WIDTH:4;
} fLib_DMA_FEATURE_t;	
#endif

#ifndef __BIG_ENDIAN //for little endian
typedef struct
{
	UINT32 enable:1;
	UINT32 dst_sel:1;
	UINT32 src_sel:1;
	UINT32 dst_ctrl:2;
	UINT32 src_ctrl:2;
	UINT32 mode:1;
	UINT32 dst_width:3;
	UINT32 src_width:3;
	UINT32 reserved1:1;
	UINT32 abt:1;
	UINT32 src_size:3;
	UINT32 prot:3;
	UINT32 priority:2;
	UINT32 FIFO_TH:3;			//new
	UINT32 reserved0:4;			//new
	UINT32 tc_msk:1;
}fLib_DMA_CH_CSR_t;
#else //for big endian
typedef struct
{
	UINT32 tc_msk:1;
	UINT32 reserved0:4;			//new
	UINT32 FIFO_TH:3;			//new
	UINT32 priority:2;
	UINT32 prot:3;
	UINT32 src_size:3;
	UINT32 abt:1;
	UINT32 reserved1:1;
	UINT32 src_width:3;
	UINT32 dst_width:3;
	UINT32 mode:1;
	UINT32 src_ctrl:2;
	UINT32 dst_ctrl:2;
	UINT32 src_sel:1;
	UINT32 dst_sel:1;
	UINT32 enable:1;
}fLib_DMA_CH_CSR_t;
#endif

#ifndef __BIG_ENDIAN //for little endian
typedef struct
{
	UINT32 int_tc_msk:1;
	UINT32 int_err_msk:1;
	UINT32 int_abt_msk:1;   //new
	UINT32 SRC_RS:4;		//new
	UINT32 SRC_HE:1;		//new
	UINT32 busy:1;		    //RO
	UINT32 DST_RS:4;		//new
	UINT32 DST_EN:1;		//new
	UINT32 reserved1:2;		//new
	UINT32 llp_cnt:4;       //new
	UINT32 reserved2:12;
}fLib_DMA_CH_CFG_t;
#else //for big endian
typedef struct
{
	UINT32 reserved2:12;
	UINT32 llp_cnt:4;       //new
	UINT32 reserved1:2;		//new
	UINT32 DST_EN:1;		//new
	UINT32 DST_RS:1;		//new
	UINT32 busy:1;		    //RO
	UINT32 SRC_HE:4;		//new
	UINT32 SRC_RS:4;		//new
	UINT32 int_abt_msk:1;   //new
	UINT32 int_err_msk:1;
	UINT32 int_tc_msk:1;
}fLib_DMA_CH_CFG_t;
#endif

#ifndef __BIG_ENDIAN //for little endian
typedef struct
{
	UINT32 master_id:1;
	UINT32 reserved:1;
	UINT32 link_list_addr:30;
}fLib_DMA_CH_LLP_t;
#else //for big endian
typedef struct
{
	UINT32 link_list_addr:30;
	UINT32 reserved:1;
	UINT32 master_id:1;
}fLib_DMA_CH_LLP_t;
#endif

#ifndef __BIG_ENDIAN //for little endian
typedef struct
{
	UINT32 reserved:16;  //new, the Size is obsoleted

	UINT32 dst_sel:1;
	UINT32 src_sel:1;
	UINT32 dst_ctrl:2;
	UINT32 src_ctrl:2;
	UINT32 dst_width:3;
	UINT32 src_width:3;
	UINT32 tc_msk:1;
	UINT32 FIFO_TH:3;		//new
}fLib_DMA_LLP_CTRL_t;
#else //for big endian
typedef struct
{
	UINT32 FIFO_TH:3;		//new
	UINT32 tc_msk:1;
	UINT32 src_width:3;
	UINT32 dst_width:3;
	UINT32 src_ctrl:2;
	UINT32 dst_ctrl:2;
	UINT32 src_sel:1;
	UINT32 dst_sel:1;

	UINT32 reserved:16;  //new, the Size is obsoleted
}fLib_DMA_LLP_CTRL_t;
#endif

typedef struct
{
	volatile fLib_DMA_CH_CSR_t csr;
	volatile fLib_DMA_CH_CFG_t cfg;
	volatile UINT32 src_addr;
	volatile UINT32 dst_addr;
	volatile fLib_DMA_CH_LLP_t llp;
	volatile UINT32 size;		//the unit is SrcWidth
	volatile UINT32 dummy[2];
}fLib_DMA_CH_t;

typedef struct
{
	UINT32 src_addr;
	UINT32 dst_addr;
	fLib_DMA_CH_LLP_t llp;
	fLib_DMA_LLP_CTRL_t llp_ctrl;
	UINT32 TotalSize;		//new, the unit is SrcWidth, only 21 bits is used
	UINT32 Dummy[3];		//this is for program to look nice.
}fLib_DMA_LLD_t;


typedef struct
{
	volatile UINT32 dma_int;
	volatile UINT32 dma_int_tc;
	volatile UINT32 dma_int_tc_clr;
	volatile UINT32 dma_int_err;
	volatile UINT32 dma_int_err_clr;
	volatile UINT32 dma_tc;
	volatile UINT32 dma_err;
	volatile UINT32 dma_ch_enable;
	volatile UINT32 dma_ch_busy;
	volatile UINT32 dma_csr;
	volatile UINT32 dma_sync;
	volatile UINT32 dummy0[5];
	volatile UINT32 dummy1[12*4];
	volatile fLib_DMA_CH_t dma_ch[8];
}fLib_DMA_Reg_st;


/*  -------------------------------------------------------------------------------
 *   API
 *  -------------------------------------------------------------------------------
 */

extern int    fLib_IsDMAChannelBusy(INT32 Channel);
extern int    fLib_IsDMAChannelEnable(INT32 Channel);
extern UINT32 fLib_GetDMAIntStatus(void);
extern UINT32 fLib_GetDMAChannelIntStatus(INT32 Channel);
extern int    fLib_GetDMABusyStatus(void);
extern int    fLib_GetDMAEnableStatus(void);

extern void   fLib_InitDMA(UINT32 M0_BigEndian, UINT32 M1_BigEndian, UINT32 Sync);
extern void   fLib_EnableDMAChannel(INT32 Channel);

extern void   fLib_DisableDMAChannel(INT32 Channel);  

extern void   fLib_ClearDMAChannelIntStatus(INT32 Channel);
extern void   fLib_AbortDMAChannel(INT32 Channel);  

extern void   fLib_SetDMAChannelCfg(INT32 Channel, fLib_DMA_CH_CSR_t Csr);
extern void	  fLib_SetDMAChannelCnCfg(INT32 Channel, fLib_DMA_CH_CFG_t CnCfg);
extern fLib_DMA_CH_CSR_t fLib_GetDMAChannelCfg(INT32 Channel);
extern void   fLib_DMA_CHIntMask(INT32 Channel, fLib_DMA_CH_CFG_t Mask);
extern void   fLib_DMA_CHLinkList(INT32 Channel, fLib_DMA_CH_LLP_t LLP);
extern void   fLib_DMA_CHDataCtrl(INT32 Channel, UINT32 SrcAddr, UINT32 DstAddr, UINT32 Size);

extern UINT32 fLib_DMA_NormalMode(
UINT32 Channel,   // use which channel for AHB DMA, 0..7
UINT32 LinkAddr,  // Link-List address, an pre-assigned space for link list
UINT32 LLPCount,  // total link-list node, if NO link list is needed, LLPCount is 0
UINT32 SrcAddr,   // source begin address
UINT32 DstAddr,   // dest begin address
UINT32 Size,      // total bytes
UINT32 SrcWidth,  // source width 8/16/32 bits -> 0/1/2
UINT32 DstWidth,  // dest width 8/16/32 bits -> 0/1/2
UINT32 SrcSize,   // source burst size, How many "SrcWidth" will be transmmited at one times ?
UINT32 SrcCtrl,   // source address change : Inc/dec/fixed --> 0/1/2
UINT32 DstCtrl,   // dest address change : Inc/dec/fixed --> 0/1/2
UINT32 Priority,  // priority for this chaanel 0(low)/1/2/3(high)
UINT32 Mode,       // Normal/Hardwire,   0/1
UINT32 FIFO_TH,		//FIFO threshhold
UINT32 Src_sel,
UINT32 Dst_sel,
UINT32 Protection
);


extern void fLib_DMA_SetInterrupt(UINT32 channel, UINT32 tcintr, UINT32 errintr, UINT32 abtintr);
extern void fLib_DMA_ResetChannel(UINT8 channel);
extern void fLib_DMA_ClearAllInterrupt(void);
extern void fLib_SetDMAChannelCfg_HW_Handshake(INT32 Channel, UINT32 SRC_HE, UINT32 SRC_REQ, UINT32 DST_HE, UINT32 DST_REQ);
void fLib_DMA_WaitIntStatus(UINT32 Channel);
int fLib_DMA_ISChannelEnable(INT32 Channel);
int fLib_DMATest_new(UINT32 mode);
int fLib_CompareMemory(UINT32 *SrcAddr, UINT32 *DstAddr, UINT32 Size);
int fLib_CheckContent(UINT32 *DstAddr, UINT32 Size);

#endif
